import React, { ReactNode, useRef, useState } from 'react';
import { Animated, View, StyleSheet, ScrollViewProps, Dimensions, StyleProp, ViewStyle } from 'react-native';

const { width } = Dimensions.get('window');

type StickyHeaderWrapperProps = {
    stickyHeader: ReactNode; // 吸顶前的 Header
    stickyHeaderOnSticky?: ReactNode; // 吸顶后的 Header
    stickyHeaderHeight?: number;
    stickyHeaderStyle?: StyleProp<ViewStyle>;
    scrollViewProps?: ScrollViewProps;
    children: ReactNode;
};

const StickyHeaderWrapper: React.FC<StickyHeaderWrapperProps> = ({
    stickyHeader,
    stickyHeaderOnSticky,
    stickyHeaderHeight = 60,
    stickyHeaderStyle = {},
    scrollViewProps = {},
    children,
}) => {
    const scrollY = useRef(new Animated.Value(0)).current;
    const [canScroll, setCanScroll] = useState(false);
    const [containerHeight, setContainerHeight] = useState(0);
    const [contentHeight, setContentHeight] = useState(0);
    const opacityNormal = scrollY.interpolate({
        inputRange: [stickyHeaderHeight - 50, stickyHeaderHeight],
        outputRange: [1, 0],
        extrapolate: 'clamp',
    });

    const opacitySticky = scrollY.interpolate({
        inputRange: [stickyHeaderHeight - 50, stickyHeaderHeight],
        outputRange: [0, 1],
        extrapolate: 'clamp',
    });

    const scale = scrollY.interpolate({
        inputRange: [stickyHeaderHeight - 50, stickyHeaderHeight],
        outputRange: [0.95, 1],
        extrapolate: 'clamp',
    });
    const effectiveScrollY = canScroll ? scrollY : new Animated.Value(0);
    const opacityStickyWrapper = effectiveScrollY.interpolate({
        inputRange: [-50, 0, stickyHeaderHeight - 50, stickyHeaderHeight],
        outputRange: [0, 0, 1, 1],
        extrapolate: 'clamp',
    });

    return (
        <View style={{ flex: 1 }}>
            <Animated.View
                style={[
                    styles.stickyHeader,
                    {
                        height: stickyHeaderHeight,
                        width,
                        transform: [{ scale }],
                        opacity: opacityStickyWrapper,
                        zIndex: 9999,
                    },
                    stickyHeaderStyle,
                ]}>
                {/* 未吸顶 header */}
                <Animated.View
                    pointerEvents={canScroll ? 'auto' : 'box-none'}
                    style={[StyleSheet.absoluteFillObject, { opacity: opacityNormal }]}>
                    {stickyHeader}
                </Animated.View>

                {/* 吸顶后 header */}
                {stickyHeaderOnSticky && (
                    <Animated.View
                        pointerEvents={canScroll ? 'auto' : 'none'}
                        style={[StyleSheet.absoluteFillObject, { opacity: opacitySticky }]}>
                        {stickyHeaderOnSticky}
                    </Animated.View>
                )}
            </Animated.View>
            <Animated.ScrollView
                {...scrollViewProps}
                scrollEventThrottle={16}
                onContentSizeChange={(w, h) => {
                    setContentHeight(h);
                    setCanScroll(h > containerHeight);
                }}
                onLayout={(e) => {
                    const h = e.nativeEvent.layout.height;
                    setContainerHeight(h);
                    setCanScroll(contentHeight > h);
                }}
                onScroll={
                    canScroll
                        ? Animated.event([{ nativeEvent: { contentOffset: { y: scrollY } } }], {
                              useNativeDriver: true,
                          })
                        : undefined
                }>
                <View style={{ height: stickyHeaderHeight }}>{stickyHeader}</View>
                {children}
            </Animated.ScrollView>
        </View>
    );
};

const styles = StyleSheet.create({
    stickyHeader: {
        position: 'absolute',
        top: 0,
        left: 0,
        zIndex: 10,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'transparent',
    },
});

export default StickyHeaderWrapper;
